iT邦幫忙

2024 iThome 鐵人賽

DAY 16
2
Software Development

透過 nestjs 框架,讓 nodejs 系統維護度增加系列 第 26

nestjs 系統設計 - 活動訂票管理系統 - fly.io

  • 分享至 

  • xImage
  •  

nestjs 系統設計 - 活動訂票管理系統 - fly.io

目標

昨天做完了容器化,今天會來講述如何部屬服務到可對外服務的平台。

概念

程式開發環境與正式運營環境的差別,基本上有以下幾點:
1. 網路存取範圍: 開發環境可以是封閉的網路環境,只需要所有開發團隊與相關人員可以存取即可。正式環境需要根據服務本身的性質來作網路存取權的限制,比如:假設是一般的 api 需要提供給非惡意的使用者使用,則透過一些 reverse proxy 像是 cloudflare 的管控之下,會透過 cloudflare 來對外提供服務,因此對外的 api 權限是能讓負載均衡器的同一個虛擬內網中
2. 可用性: 是指系統在可工作狀態下的時間比例。一般來說,正式環境根據服務性質定下目標可用性。正式環境被要求的可用性基本是比開發環境來的高。
3. 資料狀態是否有備援: 正式環境最重要的是能以正常的功能服務客戶。在現行應用中,免不了有服務狀態要處理。因此,當系統出問題時,除了能夠將系統修正回可用。另一件事情就是客戶狀態的回覆,是否在系統出問題當下把執行到一半的狀態儲存下來,並且能在系統可用後,能夠回朔到出問題前。這時,資料狀態就是必須要作備援的設計,而往往在正式環境才具有這樣的成本效益。所以開發環境大多是開發者自行去把一些服務紀錄在開發的機器上,在慢慢去根據遇到錯誤來試著回朔。
4. 對隱私資料的處理: 在一些具有資訊隱私性的服務,其資料的公開存取程度,比如: 人力銀行儲存求職者個資等等,這些資料。對於非維運人員,基本上是無法去存取。而基本上為了資料隱私性,這些資訊在系統紀錄上也會採用遮罩遮去重要部份,只顯示需要處理部份。在開發環境,基本上沒有這個效益,所以會採取的措施比較少。

雖然上面講了四點,但由於目前本文所撰寫的專案屬於是開發部份。所以除了網路存取範圍會是透過 proxy 對外服務。另外,其他幾點都是沒有在設計範圍之內。這邊提出來是讓以後在開發部屬時,需要讓開發者與維運者必須有這樣的概念。

考量與配置

活動訂票與管理系統除了本身的 api 服務之外,需要以下其他資源:

  1. Postgresql 服務
  2. Redis 服務

這邊為了採取免費的方式且方便的作法預計會把主要的服務部屬到 fly.io 這個平台。而 Postgresql 會採用 neon 服務, Redis 服務則採用 upstash 服務。

fly.io 平台提供了 cli 方式,讓開發者能夠方便得出初始化服務。以及簡便透過 cli 操作部屬細節。而 fly.io 主要是透過 Dockerfile 來針對資源檔案作打包,透過 cli 產生 toml 設定檔案。這個 toml 檔是部屬服務的藍圖。

neon 設定

neon 服務是提供 Postgresql 資源的線上服務,在某些用量之下是免費的。這邊應該開發所需,所以只需要使用到免費的用量即可。

配置如下圖: 
image

在免費的方案中, region 亞洲的點,最近的區域是新加坡。然後,配置相容於 Postgresql 14 的版本,設定資料庫名稱的是 ticket-system-db 。

設定完之後可以到 Project 的 Dashboard 看到一些設置的 Postgresql 屬性如下圖

image

最關鍵在於 connection string 透過,這個屬性。為了讓系統能夠連上,資料表必須要先透過 migration 的方式建制。不同於在開發機器的配置,要連上 neon 服務的 Postgresql 會需要打開 ssl 憑證。

這部份,在原本的 dataSource 的設置原本有針對環境變數去設計,只需要讓 NODE_ENV 設定成 production,就能夠啟用 ssl 連線部份。如下圖

image

執行 migration

pnpm typeorm:run-migrations

查看 neon 服務上的資料表是否建立,如下圖

image

可以看到所有需要的 table 都透過 migration 建立起來了。

以初學 Postgresql 的開發者來說, neon 服務提供了所見即所得的操作。還有方便的圖形化界面操作。當然要更進階比如角色權限配置,需要開發者自行去查看文件來設定。但對於初學者學習來說已經很足夠。

upstash 設定

upstash 服務是提供 Redis 資源的線上服務,在某些用量之下是免費的。這邊應該開發所需,所以只需要使用到免費的用量即可。免費方案每天的 command 執行數量是 10000 個。

設置如下:
image

在免費的方案中, region 最近的資源就是新加坡。
image

一樣也是需要取的連線字串,這邊由於 ioredis 實做了解析 URL 的功能。所以只需要去帶入 URL 即可,不需要特別去調整連線參數。

fly io 配置

透過 fly io 平台提供的 cli tool ,會需要在該專案的資料夾下,執行初始化的設定。 步驟依序如下:

  1. 登入 fly.io 平台
flyctl auth login
  1. 查看過去 launch 過的 app
fly apps list

image

接下來有兩種作法,一種是手動自己調整好配置再做 deploy,另一種是直接讓 cli 自動讀取專案作自動配置。
這邊採用比較簡單的 fly launch 方式,然後再去微調整 fly.toml 的變數

  1. 建立 app 基礎配置
fly launch --no-deploy

然後就可以看到生成出一個 fly.toml 配置如下

app = 'ticket-booking-system'
primary_region = 'hkg'

[build]

[http_service]
  internal_port = 3000
  force_https = true
  auto_stop_machines = 'stop'
  auto_start_machines = true
  min_machines_running = 1
  processes = ['app']

[[vm]]
  size = 'shared-cpu-1x'

裡面是針對建制的 region 還有機器大小,這邊先採用記憶體 256 MB 的規格,後續不夠再來作調整。

以下是幾個比較重要的設定值:

  1. internal_port: 這個代表 app 該 container 會讓 load balancer 讀取的 port 需要根據開發的應用去設定,因為 nestjs 是 3000。所以設定值就是 3000
  2. min_machines_running: 最少需要多少容器啟動來作服務。這邊會假設是使用 free trial。預設會被調整成 0。假設是這樣會被 fly.io 制動去變成 suspend。所以想要一直開著就必須要調整至少是 1
  3. http_service.checks: 這部份是用來檢查 instance 是健康狀態的設定。

其他的部份就是原本 fly.io 自身機制,只是單純作開發驗證這邊不部特別去深入。

  1. 執行 deloy
    再上面參數都設定結束後,就可以執行以下指令作部屬
fly deploy

備註
關於一些比較敏感的設定檔案,需要透過以下指令設定

fly secrets set [flags] NAME=VALUE NAME=VALUE

或登入 dashboard 選到 secret 的部份作操作

查看運行 log

有兩種作法一種是透過,登入之後去 dashboard 的 live log 來看。如下圖
image

或者是直接下指令

fly logs -a $app_name

image

驗證登入

把 hostname 換成剛剛 deploy 好的 domain
image

為了怕我申請的 free trial 被打到超過流量,這邊就只顯示變數

結論

今天透過 fly.io 這個平台來實現,昨天所說的透過 git commit 更新 image,然後透過建制伺服器去更新服務。這邊為了比較簡單去展示,如何使用 cli 工具達成簡易的部屬。所以採用這樣的平台,採用這平台好處是方便近乎一鍵完成。壞處是如果要使用其他對應的服務比如說非 fly.io 本身支援的資料庫服務或是 In memory db 。就要額外把流量引到外部,不僅僅是耗時,且流量費用不好。吃力又不討好。

img

比較正式的系統,會盡可能把相依的服務放在相同的虛擬內網中。對外,在額外透過比如 Internet Gateway 等等外接到其他服務。避免浪費流量再不必要的資料轉移。

關於部屬的概念,需要考慮到每個復原元件對網路路由的連通性。簡單來說,假設今天有一個資料庫服務在一個系統中。那這個資料庫服務在系統中,有哪些服務可以存取它,它又必須要可以存取哪些服務。為了作某種通訊協定 health check ,應試把內部系統作報表的服務開到外網,這樣作路由是合理的嗎?正式環境的資料庫似乎就更不應該直接對外。

適當的部屬資源是節省資源與現在很多企業在說的網路安全基本。不是為了方便,然後就把網路資源一路對外開到底,再來詢問為何網路流量超支。


上一篇
nestjs 系統設計 - 活動訂票管理系統 containerize
下一篇
nestjs 系統設計 - 活動訂票管理系統 - client code part 1
系列文
透過 nestjs 框架,讓 nodejs 系統維護度增加31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言